/* 
*  Copyright (C) 2009-2010 WCG Project
*
*  This program is free software; you can redistribute it and/or modify it
*  under the terms of the GNU General Public License as published by the
*  Free Software Foundation; either version 2 of the License, or (at
*  your option) any later version.
*
*  This program is distributed in the hope that it will be useful, but
*  WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
*  General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program; if not, write to the Free Software Foundation,
*  Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*  In addition, as a special exception, the author gives permission to
*  link the code of this program with the Half-Life Game Engine ("HL
*  Engine") and Modified Game Libraries ("MODs") developed by Valve,
*  L.L.C ("Valve"). You must obey the GNU General Public License in all
*  respects for all of the code used other than the HL Engine and MODs
*  from Valve. If you modify this file, you may extend this exception
*  to your version of the file, but you are not obligated to do so. If
*  you do not wish to do so, delete this exception statement from your
*  version.
*/



/*
*	Common DB Functions
*/

public DB_DetermineType()
{

	new iDatabaseType = get_pcvar_num( CVAR_save_xp_db )

	// See if we can save with MySQL
	if ( iDatabaseType == DB_MYSQLX )
	{
	
		// Then we can't save using mysql
		if ( !LibraryExists( "sqlx", LibType_Class ) )
		{
			WC3_Log( true, "[WARNING] Unable to saving using MySQL, please enable the mysql module" )
			WC3_Log( true, "[WARNING] Saving (possibly) will be done by using SQLite" )
		}

		// OK we can save!
		else
		{
			g_DBType = DB_MYSQLX

			// Make sure affinity is set correctly!
			SQL_SetAffinity( "mysql" )
		}
	}

	// See if we can save with SQLite if MySQLX didn't work
	if ( g_DBType == -1 )
	{
		
		// Then we can't save w/this!!!
		if ( !LibraryExists( "sqlx", LibType_Class )  )
		{
			WC3_Log( true, "[WARNING] Unable to saving using SQLite, please enable the sqlite module" )
		}
		
		// OK we can save
		else
		{
			// We're using SQLite
			g_DBType = DB_SQLITE

			// Make sure affinity is set correctly!
			SQL_SetAffinity( "sqlite" )
		}
	}
	
	// Then we don't have a DB Type yet set up for saving! Disable saving
	if ( g_DBType == -1 )
	{
		WC3_Log( true, "[ERROR] Unable to save XP, please enable SQLite or MySQL X (mysql requires additional configuration)" )
	}
	return
}

// Function will determine what type of database we should use, then initiate the appropriate "connections"
public DB_Init()
{
	// We should only need to call this once
	if ( g_DBType == -1 )
	{
		DB_DetermineType()
	}	

	// Initiate our database
	switch( g_DBType )
	{
		case DB_MYSQLX:	MYSQLX_Init()
		case DB_SQLITE:	SQLITE_Init()
	}

	return
}

// Close the database connection(s)
public DB_Close()
{
	
	// Close our connections
	switch( g_DBType )
	{
		case DB_MYSQLX:	MYSQLX_Close()
		case DB_SQLITE:	SQLITE_Close()
	}

	return
}

// Save the user's XP
public DB_SaveXP( id, bThreaded )
{
	id = GetTaskID( id, TASK_SAVE )

	// Can't save if user's XP hasn't been retrieved yet!
	if ( !bDBXPRetrieved[id] )
		return

	// Allow bot's XP to be saved if we're saving by name
	if ( is_user_bot( id ) && get_pcvar_num( CVAR_save_by ) != DB_SAVEBY_NAME )
		return

	// Save the XP - use threaded!
	if ( bThreaded )
	{
		switch( g_DBType )
		{
			case DB_MYSQLX:	MYSQLX_Save_T( id )
			case DB_SQLITE:	SQLITE_Save_T( id )
		}
	}

	// Don't save with threaded!
	else
	{
		switch( g_DBType )
		{
			case DB_MYSQLX:	MYSQLX_Save( id )
			case DB_SQLITE:	SQLITE_Save( id )
		}
	}
}

// This function will save the XP for all players
public DB_SaveAll( bThreaded )
{
	for( new id = 1; id <= GameInfo[GI_MaxPlayers] ; id++ )
	{
		if( is_user_connected(id) )
			DB_SaveXP( id, bThreaded )
	}
}

// Function will return the appropriate key for a user
DB_GetKey( id, szKey[], len )
{

	switch( get_pcvar_num( CVAR_save_by ) )
	{
		case DB_SAVEBY_NAME:
		{
			get_user_name( id, szKey, len )

			DB_FormatString( szKey, len )
		}

		case DB_SAVEBY_IP:		get_user_ip( id, szKey, len, 1 )
		case DB_SAVEBY_STEAMID:	get_user_authid( id, szKey, len )
	}
}

// Function will return the keyname
DB_GetKeyName( szKeyName[], len )
{
	switch( get_pcvar_num( CVAR_save_by ) )
	{
		case DB_SAVEBY_NAME:	copy( szKeyName, len, "player_name" )
		case DB_SAVEBY_IP:		copy( szKeyName, len, "player_ip" )
		case DB_SAVEBY_STEAMID:	copy( szKeyName, len, "player_steamid" )
	}
}

// Function will get the user's XP for each race
public DB_GetAllXP( id )
{
	// If we're not saving XP, why do this?
	if( !id )
		return
	
	// Get the XP	
	switch( g_DBType )
	{
		case DB_MYSQLX:	MYSQLX_GetAllXP( id )
		case DB_SQLITE:	SQLITE_GetAllXP( id )
	}

	return
}

public DB_SetDataForRace( id )
{
	// If we're not saving XP, why do this?
	if( !id )
		return

	// Set the user's race information
	switch( g_DBType )
	{
		case DB_MYSQLX:	MYSQLX_SetDataForRace( id )
		case DB_SQLITE:	SQLITE_SetDataForRace( id )
	}

	return
}

// Prepares text for database insertion
public DB_FormatString( text[], len )
{
	switch( g_DBType )
	{
		case DB_MYSQLX:	replace_all( text, len, "'", "\'" )
		case DB_SQLITE:	replace_all( text, len, "'", "''" )
	}
	
}

DB_UpdateTimestamp( id )
{
	if( !id )
		return

	// Update the user's timestamp for each race
	switch( g_DBType )
	{
		case DB_MYSQLX:	MYSQLX_UpdateTimestamp( id )
		case DB_SQLITE:	SQLITE_UpdateTimestamp( id )
	}

	return
}

DB_Prune()
{
	if( !get_pcvar_num( CVAR_save_pruning ) || !get_pcvar_num( CVAR_days_before_delete ) )
		return

	// Prune the DB
	switch( g_DBType )
	{
		case DB_MYSQLX:	MYSQLX_Prune()
		case DB_SQLITE:	SQLITE_Prune()
	}

	return
}

public DB_FetchUniqueID( id )
{
	if( !id )
		return

	// Update the user's timestamp for each race
	switch( g_DBType )
	{
		case DB_MYSQLX:	MYSQLX_FetchUniqueID( id )
		case DB_SQLITE:	SQLITE_FetchUniqueID( id )
	}
	
	// Nothing was found - try again in a bit
	if ( g_iDBPlayerUniqueID[id] == 0 )
	{
		// No connection available!
		if ( !DB_Connection_Available() )
		{
			return
		}
		//WC3_Log( true, "[ERROR] Unable to retreive user's (%d) Unique ID, trying again...", id )

		set_task( 1.0, "DB_FetchUniqueID", id )
	}

	return
}

DB_GetUniqueID( id )
{
	// Then we need to determine this player's ID!
	if ( g_iDBPlayerUniqueID[id] <= 0 || get_pcvar_num( CVAR_save_by ) != g_iDBPlayerSavedBy[id] )
	{
		DB_FetchUniqueID( id )
	}

	return g_iDBPlayerUniqueID[id]
}

bool:DB_Connection_Available()
{
	// Update the user's timestamp for each race
	switch( g_DBType )
	{
		case DB_MYSQLX:	return MYSQLX_Connection_Available()
		case DB_SQLITE:	return SQLITE_Connection_Available()
	}

	return false
}